﻿using System.Windows;
using ChatClient.Services;
using ChatClient.Views;
using DotnetUtil.Extensions;
using DotnetUtil.Services;
using Prism.Ioc;
using Prism.Unity;

namespace ChatClient
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    // ReSharper disable once RedundantExtendsListEntry
    public partial class App : PrismApplication
    {
        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);

            try
            {
                //反初始化服务
                UnInitService();
            }
            catch (Exception exception)
            {
                var logService = Container.Resolve<ILogService>();
                logService.Fatal($"UnInitService error: {exception.GetFullMessage()}.");
            }
        }

        protected override Window CreateShell()
        {
            InitService(); //初始化服务
            HandleException(); //处理异常
            return Container.Resolve<LoginWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册单例服务
            containerRegistry.RegisterSingleton<ILogService, LogService>();
            containerRegistry.RegisterSingleton<IConfigService, ConfigService>();
            containerRegistry.RegisterSingleton<IChatService, ChatService>();
            containerRegistry.RegisterSingleton<IDialogService, DialogService>();
            containerRegistry.RegisterSingleton<ISessionService, SessionService>();
        }

        #region Init/UnInit Service

        private void InitService()
        {
            //启动日志服务
            var logService = Container?.Resolve<ILogService>();
            logService?.Startup();

            //初始化配置服务
            //var configService = Container?.Resolve<IConfigService>();
            //configService?.Startup(@"Config/AppSettings.xml");

            //启动Session服务
            var sessionService = Container?.Resolve<ISessionService>();
            sessionService?.Startup();
        }

        private void UnInitService()
        {
            //关闭Session服务
            var sessionService = Container?.Resolve<ISessionService>();
            sessionService?.Shutdown();

            //关闭日志服务
            var logService = Container?.Resolve<ILogService>();
            logService?.Shutdown();
        }

        #endregion

        //处理异常
        private void HandleException()
        {
            //处理除Task以外的所有线程异常
            AppDomain.CurrentDomain.UnhandledException += (_, args) =>
            {
                var logService = Container.Resolve<ILogService>();
                logService.Error($"AppDomain.CurrentDomain.UnhandledException: {args.ExceptionObject}");
            };

            //处理UI线程异常
            Current.DispatcherUnhandledException += (_, args) =>
            {
                var logService = Container.Resolve<ILogService>();
                logService.Error(
                    $"Application.Current.DispatcherUnhandledException: {args.Exception?.GetFullMessage()}");
                args.Handled = true; //标记已处理
            };

            //处理Task异常(依赖垃圾回收)
            TaskScheduler.UnobservedTaskException += (_, args) =>
            {
                var logService = Container.Resolve<ILogService>();
                logService.Error($"TaskScheduler.UnobservedTaskException: {args.Exception.GetFullMessage()}");
                args.SetObserved(); //设置异常已被观察
            };

            //Occurs when a thread exception is thrown and uncaught during execution of a delegate
            // by way of Dispatcher.Invoke or Dispatcher.BeginInvoke.
            Dispatcher.UnhandledException += (_, args) =>
            {
                var logService = Container.Resolve<ILogService>();
                logService.Error($"Dispatcher.UnhandledException: {args.Exception?.GetFullMessage()}");
                args.Handled = true; //标记已处理
            };

            //Occurs when a thread exception is thrown and uncaught during execution of a delegate
            // by way of Dispatcher.Invoke or Dispatcher.BeginInvoke.
            Dispatcher.UnhandledExceptionFilter += (_, args) =>
            {
                var logService = Container.Resolve<ILogService>();
                logService.Error($"Dispatcher.UnhandledExceptionFilter: {args.Exception?.GetFullMessage()}");
                args.RequestCatch = true; //抛出异常
            };
        }
    }
}
